
#include "lwip/opt.h"
#include "lwip/arch.h"
#include "lwip/api.h"

#include "httpserver-netconn.h"

#if LWIP_NETCONN

#ifndef HTTPD_DEBUG
#define HTTPD_DEBUG         LWIP_DBG_OFF
#endif

static const char http_html_hdr[] = "HTTP/1.1 200 OK\r\nContent-type: text/html\r\n\r\n";

static const char http_index_html[] = "<html><head><title>Congrats!</title></head>\
                                       <body><h1 align=\"center\">Hello World!</h1>\
                                       <h2 align=\"center\">Welcome to MM32 lwIP HTTP Server!</h1>\
                                       <p align=\"center\">httpserver-netconn.</p>\
                                       <p align=\"center\"><a href=\"http://www.mindmotion.com.cn/\"> <font size=\"6\"> MindMotion </font> </a></p>\
                                       <a href=\"https://www.baidu.com/\">\
                                       <p align=\"center\"><img src=\"https://seopic.699pic.com/photo/50061/8976.jpg_wh1200.jpg\" /></a>\
                                       </body></html>";

/** Serve one HTTP connection accepted in the http thread */    //http://www.firebbs.cn/data/attachment/portal/201806/05/163015rhz7mbgbt0zfujzh.jpg
static void
http_server_netconn_serve(struct netconn* conn)
{
    struct netbuf* inbuf;
    char* buf;
    u16_t buflen;
    err_t err;

    /* Read the data from the port, blocking if nothing yet there.
     We assume the request (the part we care about) is in one netbuf */
    err = netconn_recv(conn, &inbuf);

    if (err == ERR_OK) {
        netbuf_data(inbuf, (void**)&buf, &buflen);

        /* Is this an HTTP GET command? (only check the first 5 chars, since
        there are other formats for GET, and we're keeping it very simple )*/
        if (buflen >= 5 &&
                buf[0] == 'G' &&
                buf[1] == 'E' &&
                buf[2] == 'T' &&
                buf[3] == ' ' &&
                buf[4] == '/' ) {

            /* Send the HTML header
                   * subtract 1 from the size, since we dont send the \0 in the string
                   * NETCONN_NOCOPY: our data is const static, so no need to copy it
             */
            netconn_write(conn, http_html_hdr, sizeof(http_html_hdr) - 1, NETCONN_NOCOPY);

            /* Send our HTML page */
            netconn_write(conn, http_index_html, sizeof(http_index_html) - 1, NETCONN_NOCOPY);
        }
    }
    /* Close the connection (server closes in HTTP) */
    netconn_close(conn);

    /* Delete the buffer (netconn_recv gives us ownership,
     so we have to make sure to deallocate the buffer) */
    netbuf_delete(inbuf);
}

/** The main function, never returns! */
static void
http_server_netconn_thread(void* arg)
{
    struct netconn* conn, *newconn;
    err_t err;
    LWIP_UNUSED_ARG(arg);

    /* Create a new TCP connection handle */
    /* Bind to port 80 (HTTP) with default IP address */
#if LWIP_IPV6
    conn = netconn_new(NETCONN_TCP_IPV6);
    netconn_bind(conn, IP6_ADDR_ANY, LOCAL_PORT);
#else /* LWIP_IPV6 */
    conn = netconn_new(NETCONN_TCP);
    netconn_bind(conn, IP_ADDR_ANY, LOCAL_PORT);
#endif /* LWIP_IPV6 */
    LWIP_ERROR("http_server: invalid conn", (conn != NULL), return;);

    /* Put the connection into LISTEN state */
    netconn_listen(conn);

    do {
        err = netconn_accept(conn, &newconn);
        if (err == ERR_OK) {
            http_server_netconn_serve(newconn);
            netconn_delete(newconn);
        }
    } while(err == ERR_OK);
    LWIP_DEBUGF(HTTPD_DEBUG,
                ("http_server_netconn_thread: netconn_accept received error %d, shutting down",
                 err));
    netconn_close(conn);
    netconn_delete(conn);
}

/** Initialize the HTTP server (start its thread) */
void
http_server_netconn_init(void)
{
    sys_thread_new("http_server_netconn", http_server_netconn_thread, NULL, 1024, 4);
}

#endif /* LWIP_NETCONN*/
